namespace com.stifel.ServerBuildMgmt.Feature.Features.ServerBuildMgmt_Feature
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using System.Xml;

    using com.stifel.Extensions.AssemblyExtensions;
    using com.stifel.Extensions.SharePointExtensions;

    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Security;

    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>
    [Guid( "0ed2cf80-6a40-4ef2-a946-6a6672806b74" )]
    public class ServerBuildMgmt_FeatureEventReceiver : SPFeatureReceiver
    {
        #region Fields

        public const string FEATURE = "com.stifel.ServerBuildMgmt";
        public const string GUID = "0ed2cf80-6a40-4ef2-a946-6a6672806b74";

        #endregion Fields

        #region Methods

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            if ( !( properties.Feature.Parent is SPWeb ) )
            {
                ULS.LogCritical( "{0} :: Error activating feature. Feature parent is not of type SPWeb.", ULS.Category.FeatureInfrastructure, FEATURE );
                return;
            }

            string webUrl = properties.GetUrl( );
            ULS.LogMessage( "{0} :: Feature activating at {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, webUrl );
            addFields( properties );
            createContentTypes( properties );
            ULS.LogMessage( "{0} :: Feature activated at {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, webUrl );
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            if ( !( properties.Feature.Parent is SPWeb ) )
            {
                ULS.LogCritical( "{0} :: Error deactivating feature. Feature parent is not of type SPWeb.", ULS.Category.FeatureInfrastructure, FEATURE );
                return;
            }

            string webUrl = properties.GetUrl( );
            ULS.LogMessage( "{0} :: Feature deactivating from {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, webUrl );
            removeFields( properties );
            ULS.LogMessage( "{0} :: Feature deactivated from {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, webUrl );
        }

        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            ULS.LogMessage( "{0} :: Feature installed at {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, properties.GetUrl( ) );
        }

        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            ULS.LogMessage( "{0} :: Feature uninstalling at {1}.", ULS.Category.FeatureInfrastructure, ULS.Level.Information, FEATURE, properties.GetUrl( ) );
        }

        void addFields( SPFeatureReceiverProperties properties )
        {
            XmlNodeList fields = getFieldDefinitionsAsXml( properties );
            if ( fields != null )
            {
                using ( SPWeb spWeb = properties.GetWeb( ) )
                {
                    foreach ( XmlNode field in fields )
                    {
                        XmlAttribute a = field.Attributes[ "Name" ];
                        if ( a != null )
                        {
                            string name = a.Value;
                            if ( !spWeb.Fields.ContainsFieldWithStaticName( name ) )
                                spWeb.Fields.AddFieldAsXml( field.OuterXml );
                        }
                    }
                }
            }
        }

        void createContentTypes( SPFeatureReceiverProperties properties )
        {
            //StifelProject_createContentType( properties );
            //StifelTask_createContentType( properties );
        }

        void deleteContentTypes( SPFeatureReceiverProperties properties )
        {
            //StifelProject_deleteContentType( properties );
            //StifelTask_deleteContentType( properties );
        }

        XmlNodeList getFieldDefinitionsAsXml( SPFeatureReceiverProperties properties )
        {
            XmlNodeList fields = null;
            string s = Assembly.GetExecutingAssembly( ).GetFullyQualifiedManifestResourceName( "projects.fields.xml" );
            string xml = Assembly.GetExecutingAssembly( ).GetManifestResourceAsString( s );
            if ( !string.IsNullOrEmpty( xml ) )
            {
                XmlDocument d = new XmlDocument( );
                d.LoadXml( xml );
                XmlNode n = d.SelectSingleNode( "Fields" );
                fields = n.SelectNodes( "Field" );
            }
            return fields;
        }

        void removeFields( SPFeatureReceiverProperties properties )
        {
            XmlNodeList fields = getFieldDefinitionsAsXml( properties );
            if ( fields != null )
            {
                using ( SPWeb spWeb = properties.GetWeb( ) )
                {
                    foreach ( XmlNode field in fields )
                    {
                        XmlAttribute a = field.Attributes[ "Name" ];
                        if ( a != null )
                        {
                            string name = a.Value;
                            if ( spWeb.Fields.ContainsFieldWithStaticName( name ) )
                            {
                                SPField f = spWeb.Fields.GetFieldByInternalName( name );
                                if ( !f.UsedInWebContentTypes )
                                    spWeb.Fields.Delete( name );
                            }
                        }
                    }
                }
            }
        }

        #endregion Methods

        #region Other

        // Uncomment the method below to handle the event raised when a feature is upgrading.
        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}

        #endregion Other
    }
}